fix: bound plain-text runs in parse_prompt_attention regex - #1919
fix: bound plain-text runs in parse_prompt_attention regex#1919fszontagh wants to merge 3 commits into
Conversation
leejet
left a comment
There was a problem hiding this comment.
The plain-text repetition is bounded now, but the same stack-overflow path still exists in the weight alternative: :([+-]?[.\d]+)\) contains another unbounded +.
With libstdc++ (g++ 14.2, default 8 MiB stack), the PR still segfaults for e.g.:
":" + std::string(30000, '1')A closing ) is not required: the regex recursively consumes the digit run while attempting the weight alternative before falling back to the literal : alternative.
Could we bound the numeric run as well (to a realistic float length), or avoid unbounded std::regex repetitions in this lexer entirely? We should also make sure oversized/invalid weights cannot terminate through std::stof.
|
Good catch, thanks. Bounded the weight run as well and switched the parse to I had missed it because my equivalence harness ran at Parsing is unchanged - old vs new output is byte-identical across weighted parens, nested brackets, escapes, |
Summary
parse_prompt_attentionlexes the prompt with an unbounded plain-text alternative. libstdc++'sstd::regexrecurses once per matched character, so a prompt of a few tens of kilobytes overflows the stack and segfaults before tokenization.Bound the run length. Splitting a long run is safe because the function's final pass merges adjacent segments of equal weight, and
Bis excluded from the character class, so a chunk boundary can never fall inside aBREAK.Related Issue / Discussion
None.
Additional Information
A 45KB prompt exits 139 (SIGSEGV) during tokenization before the change and completes normally after it.
Parsing results are unchanged: comparing old and new output across weighted parentheses, nested
((...)),[...], escaped\(, multipleBREAKs,BREAKINGand bareB, bare colons, the empty string, multi-byte UTF-8, and a 21KB run both bare and inside(...:1.3), every case is byte-identical.Checklist